home *** CD-ROM | disk | FTP | other *** search
- ;* GCMARK.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Mark unused stuff for Garbage collecting *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
-
- CODESEG
-
- ;************************************************************************
- ;* gcmark entry point *
- ;************************************************************************
- PROC C gcmark USES si di, $$pagenumber, $$displacement
- mov bx, [$$pagenumber]
- mov ax, bx
- mov si, [$$displacement] ; pointer gonna be in es:si
- call $$markrecurse
- ret
-
- PROC NOLANGUAGE $$markrecurse NEAR
- cmp bx, DEDPAGES*2 ; check for non-gc'ed pages
- jge @@domark
- ret
-
- @@domark:
- push ax ; Preserve the page number
- test bx, 0ff01h ; valid pointer?
- jnz @@badpointer
- ldpage es, bx
- mov ax, bx ; Use ax to store page number
- mov di, [WORD ptype+bx] ; load data type*2
- cmp di, NUMTYPES*2 ; valid page type?
- jae @@badpointer
- jmp [@@table+di]
- DATASEG
- @@table DW @@list ; [0] List cells
- DW @@fixnum ; [1] Fixnums
- DW @@flonum ; [2] Flonums
- DW @@bignum ; [3] Bignums
- DW @@symbol ; [4] Symbols
- DW @@string ; [5] Strings
- DW @@array ; [6] Arrays
- DW @@continuation ; [7] Continuations
- DW @@closure ; [8] Closures
- DW @@free ; [9] Free page
- DW @@code ; [10] Code page
- DW @@inline ; [11] Inline code
- DW @@port ; [12] Port data objects
- DW @@char ; [13] Characters
- DW @@environment ; [14] Environments
- CODESEG
-
- @@badpointer:
- @@fixnum:
- @@char:
- @@free:
- push ax
- lea ax, [@@msg]
- DATASEG
- @@msg DB "[VM INTERNAL ERROR] gcmark: invalid pointer: %x:%04x (from %x:%04x)", LF, 0
- CODESEG
- call zprintf C, ax, bx, si, [$$pagenumber], [$$displacement]
- call force_debug C ; go into debug mode
- pop ax
- jmp @@exit
-
- @@port: ; Process symbol or port
- @@symbol:
- test [(SYMDEF es:si).gc], GC_BIT
- jz @@symbolcontinue
- jmp @@exit
- @@symbolcontinue:
- or [(SYMDEF es:si).gc], GC_BIT
- mov bl, [(SYMDEF es:si).link.page]
- mov si, [(SYMDEF es:si).link.disp]
- pop ax ; restore saved page number
- ldpage es, ax
- jmp $$markrecurse ; make a tail recursive call to gcmark
-
- @@list: ; Process List Cell
- test [(LISTDEF es:si).gc], GC_BIT
- jnz @@exit
- mov bl, [(LISTDEF es:si).car.page]
- or [(LISTDEF es:si).gc], GC_BIT
- cmp bx, DEDPAGES*2 ; check for non-gc'ed pages
- jl @@cardone
-
- push ax bx ; Test for stack overflow
- call checkstack C
- pop bx ax
-
- push si ; list offset
- mov si, [(LISTDEF es:si).car.disp]
- and bl, NOT GC_BIT
- call @@domark
- pop si ; list offset
- @@cardone:
- mov bl, [(LISTDEF es:si).cdr.page]
- mov si, [(LISTDEF es:si).cdr.disp]
- pop ax ; restore saved page
- ldpage es, ax
- jmp $$markrecurse ; call gcmark tail recursively
-
- @@flonum: ; ref to var. length data object or flonum
- @@bignum:
- @@string:
- @@inline:
- or [(ANYDEF es:si).gc], GC_BIT
- @@exit:
- pop ax ; restore saved page
- ldpage es, ax
- ret
-
- @@code: ; Process Code Block
- test [(CODEDEF es:si).gc], GC_BIT
- jnz @@exit
- or [(CODEDEF es:si).gc], GC_BIT
- mov cx, [(CODEDEF es:si).entry.val]; load entry point offset as counter
- jmp @@testandloop
-
- @@array: ; process Variable Length Object Containing Pointers
- @@closure:
- @@continuation:
- @@environment:
- test [(ANYDEF es:si).gc], GC_BIT
- jnz @@exit
- or [(ANYDEF es:si).gc], GC_BIT
- mov cx, [(ANYDEF es:si).len]
- cmp cx, SIZE POINTER ; test for zero length vector
- jle @@exit
- @@testandloop: ; test for stack overflow
- push ax
- call checkstack C
- pop ax
- @@loop:
- add si, SIZE POINTER ; Increment address for next pointer
- push cx si ; Save counter & current offset
- mov bl, [(POINTER es:si).page]
- mov si, [(POINTER es:si).disp]
- call $$markrecurse
- pop si cx ; Restore current offset & counter
- sub cx, SIZE POINTER
- cmp cx, SIZE POINTER ; test for completion
- jg @@loop
- jmp @@exit
- ENDP $$markrecurse
-
- ENDP gcmark
-
- ;************************************************************************
- ;* sum_space *
- ;************************************************************************
- PROC C sum_space USES si di, @@result
- mov di, [@@result]
- xor bx, bx ; start with zero-th page
- @@pageloop:
- xor ax, ax ; clear the free space counter
- cmp bx, DEDPAGES*2
- jl @@done
- test [attrib+bx], NOMEMORY ; is page allocated ?
- jnz @@done
- cmp [ptype+bx], FREETYPE ; is page free ?
- je @@free
- ldpage es, bx ; load current paragraph's base address
- mov si, [WORD ptype+bx]
- jmp [@@table+si] ; branch on page type
-
- @@list:
- mov cx, SIZE LISTDEF
- @@linkedlist:
- mov si, [nextcell+bx] ; load list cell free storage chain header
- @@linkloop:
- cmp si, END_LIST ; end of list?
- je @@done
- add ax, cx ; increment the free list cell counter
- jo @@suckinloop
- mov si, [(LISTDEF es:si).car.disp]
- jmp @@linkloop ; keep following linked list
- DATASEG
- @@table DW @@list ; [0] List cells
- DW @@fixnum ; [1] Fixnums
- DW @@flonum ; [2] Flonums
- DW @@bignum ; [3] Bignums
- DW @@symbol ; [4] Symbols
- DW @@string ; [5] Strings
- DW @@array ; [6] Arrays
- DW @@continuation ; [7] Continuations
- DW @@closure ; [8] Closures
- DW @@free ; [9] Free page
- DW @@code ; [10] Code page
- DW @@inline ; [11] Inline code
- DW @@port ; [12] Port data objects
- DW @@char ; [13] Characters
- DW @@environment ; [14] Environments
- CODESEG
-
- @@bignum:
- @@symbol:
- @@string:
- @@inline:
- @@closure:
- @@continuation:
- @@array:
- @@code:
- @@port:
- @@environment:
- xor si, si ; initialize pointer into page
- mov cx, [psize+bx]
- sub cx, SIZE POINTER ; adjust size for page boundary check
- @@itemloop:
- cmp si, cx ; through with this page?
- ja @@done
- mov dx, [(ANYDEF es:si).len]
- or dx, dx ; check for small string
- jge @@bigstr
- mov dx, OFFSET (TYPE STRDEF).buffer + SIZE POINTER
- @@bigstr:
- cmp [(FREEDEF es:si).tag], FREETYPE
- jne @@used
- add ax, dx ; add in number of free bytes
- @@used:
- add si, dx ; update pointer to next block
- jmp @@itemloop
- @@free:
- mov ax, [psize+bx] ; load size of free page
- @@fixnum:
- @@char:
- @@done:
- mov [di], ax ; store number of free bytes (ax)
- add di, 2 ; increment array index
- add bx, 2 ; increment page index
- cmp bx, NUMPAGES*2 ; test for completion
- jl @@pageloop
- ret
-
- @@flonum:
- mov cx, SIZE FLODEF
- jmp @@linkedlist
-
- @@suckinloop:
- shr bx, 1
- lea si, [@@msg]
- DATASEG
- @@msg DB "[VM FATAL ERROR] sumspace: infinite loop page %d", LF, 0
- CODESEG
- call zprintf C, si, bx
- call force_reset C ; return to scheme for debug
- ENDP sum_space
-
- END
-